////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file   CollabRCBot\LhsTreeNode.h
///
/// @brief  Declares the CollabRC::Bot::AI::LhsTreeNode class
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#include "OperationTreeNode.h"

namespace CollabRC
{
    namespace Bot
    {
        namespace AI
        {
            /**
             * @brief Implementation of an OperationTreeNode which
             * returns the left hand side, discarding the right hand side.
             * 
             * For optimization reasons, when this object is cloned, a clone
             * of the left hand side is returned instead, resulting in discarding
             * the right hand side permanently. This has potential benefits
             * to mutations as well by eliminating unsubstantiated branches.
             * @version $Id$
             * @author mpdelbuono
             */
            class LhsTreeNode : public OperationTreeNode
            {
            private:
                class Factory : public OperationTreeNode::OperationTreeNodeFactory
                {
                public:
                    inline Factory() { OperationTreeNode::RegisterOperationTreeNodeFactory(this); };
                    ComputationalTreeNode* Instantiate(const ComputationalTreeNode& lhs, const ComputationalTreeNode& rhs) const;
                };

                /// The left hand branch which is used in the computation
                const ComputationalTreeNode* const m_branch;
                static Factory factory;

                const LhsTreeNode& operator =(const LhsTreeNode&);
            public:
                LhsTreeNode(const ComputationalTreeNode& lhs, const ComputationalTreeNode& rhs);
                LhsTreeNode(const OperationTreeNode &copy);
                virtual ~LhsTreeNode(void);

                float PerformOperation(float lhs, float rhs) const;
                ComputationalTreeNode* Clone() const;
                virtual void Accept(ComputationalTreeNodeVisitor& visitor);
            };

        }
    }
}
